import java.util.LinkedList;
import java.util.Queue;

class ProdConsUsingWaitNotify {
	public static void main(String args[]) {
		ProducerConsumer pc = new ProducerConsumer();
		Thread t1 = new Producer2(pc);
		Thread t2 = new Consumer2(pc);
		t1.start();
		t2.start();

	}
}

class ProducerConsumer {
	Queue<Integer> queue = new LinkedList<Integer>();
	boolean pTurn = true;

	public synchronized void produce(int i) {
		while (!pTurn) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		queue.add(i);
		System.out.println("Produced : " + i);
		pTurn = false;
		notifyAll();
	}

	public synchronized void consume() {
		while (pTurn) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("consumed : " + queue.remove());
		pTurn = true;
		notifyAll();

	}
}

class Consumer2 extends Thread {
	private ProducerConsumer pcObj = null;

	Consumer2(ProducerConsumer pc) {
		this.pcObj = pc;
	}

	public void run() {
		while (true) {
			try {
				pcObj.consume();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

class Producer2 extends Thread {
	// This will be assigned in the constructor
	private ProducerConsumer pcObj = null;

	Producer2(ProducerConsumer pc) {
		this.pcObj = pc;
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				pcObj.produce(i);
			} catch (Exception ex) {
			}
		}
	}

}